﻿#region Namespace References

using System;
using System.Windows.Forms;
using DynConDevCorp.OpenArch.SmartData.Interfaces;
using DynConDevCorp.OpenArch.SmartData.Interfaces.EventArgClasses;

#endregion

namespace DynConDevCorp.OpenArch.SmartData.WinForms.ControlBinders
{
    /// <summary>
    /// 
    /// </summary>
    public abstract class SmartControlBinder : IDisposable
    {
        #region IDisposable Members

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            if (m_BoundControl != null)
            {
                ReleaseBoundControl();
                m_BoundControl = null;
            }
            if (m_BoundSmartField != null)
            {
                ReleaseBoundSmartField();
                m_BoundSmartField = null;
            }
        }

        #endregion

        #region Public Instance Properties

        /// <summary>
        /// Gets or sets the bound control.
        /// </summary>
        /// <value>The bound control.</value>
        public Control BoundControl
        {
            get { return m_BoundControl; }
            set
            {
                if (m_BoundControl != null)
                    ReleaseBoundControl();
                m_BoundControl = value;
                if (m_BoundControl != null)
                    UpdateBoundControl();
            }
        }

        /// <summary>
        /// Gets or sets the bound smart field.
        /// </summary>
        /// <value>The bound smart field.</value>
        public ISmartField BoundSmartField
        {
            get { return m_BoundSmartField; }
            set
            {
                if (m_BoundSmartField != null)
                    ReleaseBoundSmartField();
                m_BoundSmartField = value;
                if (m_BoundSmartField != null)
                    UpdateBoundSmartField();
            }
        }

        /// <summary>
        /// Gets or sets the containing control.
        /// </summary>
        /// <value>The containing control.</value>
        public SmartFieldControl ContainingControl
        {
            get { return m_ContainingControl; }
            set
            {
                m_ContainingControl = value;
                ConfigureContainingControl();
            }
        }

        /// <summary>
        /// Gets or sets the input update.
        /// </summary>
        /// <value>The input update.</value>
        public virtual InputUpdateMode InputUpdate { get; set; }

        /// <summary>
        /// Gets or sets the text align.
        /// </summary>
        /// <value>The text align.</value>
        public virtual HorizontalAlignment TextAlign { get; set; }

        #endregion

        #region Protected Instance Methods

        /// <summary>
        /// Configures the containing control.
        /// </summary>
        protected virtual void ConfigureContainingControl()
        {
        }

        /// <summary>
        /// Releases the bound control.
        /// </summary>
        protected virtual void ReleaseBoundControl()
        {
        }

        /// <summary>
        /// Releases the bound smart field.
        /// </summary>
        protected virtual void ReleaseBoundSmartField()
        {
            m_BoundSmartField.DisplayValueChanged -= m_BoundSmartField_DisplayValueChanged;
        }

        /// <summary>
        /// Sets the display value.
        /// </summary>
        /// <param name="value">The value.</param>
        protected virtual void SetDisplayValue(string value)
        {
        }

        /// <summary>
        /// Updates the bound control.
        /// </summary>
        protected virtual void UpdateBoundControl()
        {
        }

        /// <summary>
        /// Updates the bound smart field.
        /// </summary>
        protected virtual void UpdateBoundSmartField()
        {
            m_BoundSmartField.DisplayValueChanged += m_BoundSmartField_DisplayValueChanged;
            SetDisplayValue(m_BoundSmartField.DisplayValue);
        }

        #endregion

        #region Private Instance Methods

        private void m_BoundSmartField_DisplayValueChanged(object sender, DisplayValueChangedEventArgs e)
        {
            SetDisplayValue(e.NewDisplayValue);
        }

        #endregion

        #region Fields and Constants

        private Control m_BoundControl;
        private ISmartField m_BoundSmartField;
        private SmartFieldControl m_ContainingControl;

        #endregion
    }

    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="TControl">The type of the control.</typeparam>
    public abstract class SmartControlBinder<TControl> : SmartControlBinder
        where TControl : Control
    {
        #region Protected Instance Properties

        /// <summary>
        /// Gets or sets the typed bound control.
        /// </summary>
        /// <value>The typed bound control.</value>
        protected TControl TypedBoundControl { get; set; }

        #endregion

        #region Protected Instance Methods

        /// <summary>
        /// Updates the bound control.
        /// </summary>
        protected override void UpdateBoundControl()
        {
            TypedBoundControl = BoundControl as TControl;
        }

        #endregion
    }
}